import type { ComponentStyleIdType } from '../../types/interfaces'
import type { PanelProps } from './types'
import { UIComponent } from '../../lib/abstract'
import { ComponentStyleId } from '../../types/constants'
import { styles } from './styles'
import { DEFAULT_PANEL_PROPS, PANEL_TYPE_CONFIG } from './types'

export class CollapsiblePanel extends UIComponent<PanelProps> {
  id: string = 'collapsible-panel'
  readonly description: string = '可折叠内容面板'
  readonly styleId: string = ComponentStyleId[this.name]
  private isOpen: boolean
  private toggleIcons: Record<string, string> = {
    // 箭头图标向下
    close: `
      <svg class="dropdown-chevron" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none">
        <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
        <path d="M6 9l6 6l6 -6" />
        </svg>`,
    // 箭头图标向上
    open: `
      <svg class="dropdown-chevron" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none">
        <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
        <path d="M6 15l6 -6l6 6" />
      </svg>`,
  }

  get name(): ComponentStyleIdType {
    return 'CollapsiblePanel'
  }

  get className(): string {
    return 'custom-panel'
  }

  constructor(props: PanelProps) {
    super({
      ...DEFAULT_PANEL_PROPS,
      ...props,
    })

    this.isOpen = !this.props.collapsible || false

    // 注册样式
    this.registerStyles()
  }

  ELEMENT_SELECTORS = {
    panelHeader: { selector: `.panel-container #${this.props.id}`, dynamic: false, unique: true },
  }

  render(): string {
    const { id, type = 'note', title = type.toUpperCase(), content, collapsible, className, timeContent } = this.props as PanelProps
    const config = PANEL_TYPE_CONFIG[type]

    return `
      <div class="${this.className} ${className || ''}">
        <div class="panel-container ${type}">
          <div class="panel-header" id="${id}">
            <div class="header-content">
              <span class="panel-icon">${config.icon}</span>
              <span class="panel-title">${title}</span>
              ${timeContent ? `<span class="panel-time">${timeContent}</span>` : ''}
            </div>
            ${collapsible ? this.renderButton() : ''}
          </div>

          <div 
            id="content-${id}" 
            class="panel-content"
            aria-labelledby="${id}"
            ${collapsible ? '' : 'style="display: block;"'}
          >
            ${content}
          </div>
        </div>
      </div>
    `
  }

  renderButton() {
    const { id } = this.props as PanelProps
    const icon = this.isOpen ? this.toggleIcons.open : this.toggleIcons.close

    return `
      <button 
      id="button-${id}"
      class="toggle-button"
      aria-expanded="${this.isOpen}"
      aria-controls="content-${id}"
      >
      <span class="toggle-icon">${icon}</span>
    </button>`
  }

  bindEvents(): void {
    if (!this.props.collapsible)
      return

    const $panelHeader = this.getElement('panelHeader')

    if (!$panelHeader || !$panelHeader.length)
      return

    $panelHeader
      .off('click')
      .on('click', (e) => {
        e.stopPropagation()

        const $element = $(e.currentTarget as HTMLElement)
        // 这里为了安全，直接通过触发元素来查找需要的元素，避免意外影响其他元素
        const $content = $element.next('.panel-content')
        const $button = $element.find('.toggle-button')

        this.toggleState($button, $content)
        this.props.onToggle?.()
      })
  }

  private toggleState($button: JQuery, $content: JQuery | undefined) {
    this.isOpen = !this.isOpen

    $content?.toggleClass('is-open', this.isOpen)

    $button.attr('aria-expanded', String(this.isOpen))
    $button.find('.toggle-icon').html(this.isOpen ? this.toggleIcons.open : this.toggleIcons.close)
  }

  getStyles(): string {
    return styles()
  }

  reset(): void {
    super.reset()
  }

  destroy(): void {
    super.destroy()
  }

  removeEventListeners(): void {
    if (this.props.collapsible) {
      this.getElement('panelHeader')?.off('click')
    }
  }
}
